package cn.edu.sjtu.se.dslab.rhapsody.service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import cn.edu.sjtu.se.dslab.component.aadl.AADLModel;
import cn.edu.sjtu.se.dslab.component.aadl.AADLNode;
import cn.edu.sjtu.se.dslab.component.aadl.AADLParser;
import cn.edu.sjtu.se.dslab.component.data.AvionicsEquipment;
import cn.edu.sjtu.se.dslab.project.Project;
import cn.edu.sjtu.se.dslab.rhapsody.entity.Actor;
import cn.edu.sjtu.se.dslab.rhapsody.entity.Device;
import cn.edu.sjtu.se.dslab.service.IAvionicsEquipmentService;
import cn.edu.sjtu.se.dslab.service.IProjectService;
import cn.edu.sjtu.se.dslab.util.Const;
import cn.edu.sjtu.se.dslab.util.FileUtil;
import cn.edu.sjtu.se.dslab.util.MD5;


@Service("actorDeviceGenerator")
public class ActorDeviceGenerator extends RhapsodyFileGenerator {
	private static final Logger logger = Logger.getLogger(ActorDeviceGenerator.class);
	
	private static final String TEMPLATE_NAME = "actors.vm";
	
	@Resource(name="aadlParser")
	private AADLParser aadlParser;
	
	@Resource(name="projectService")
	private IProjectService projectService;
	
	@Resource(name="avionicsEquipmentService")
	private IAvionicsEquipmentService avionicsEquipmentService;
	
	public ActorDeviceGenerator(){
		
	}

	@Override
	public String generateFile(long projectId) throws IOException {
		Project project = projectService.getProjectById(projectId);
		AADLModel aadlModel = project.getModel();
		StringBuilder aadlPath = new StringBuilder(FileUtil.getRootPath());
		aadlPath.append("generate/").append(aadlModel.getXmlPath());
		File f = new File(aadlPath.toString());
		List<Actor> actors = new ArrayList<Actor>();
		
		for (AvionicsEquipment ae : aadlParser.parseAADLToSysmlActor(f)){
			logger.info(ae.getName());
			Actor actor = new Actor();
			actor.setName(ae.getName());
			actor.setId(generateXmiId(ae.getUri()));
			actors.add(actor);
		}
		for (AADLNode an : aadlParser.parseAADLToInnerSystem(f)){
			logger.info(an.getName());
			Device device = new Device();
			if (an.getIsMain().equals(Const.AADL_DIAGRAM_TYPE_ISMAIN_SYSTEM)){
				device.setMainControl(true);
				device.setMainControlId(generateId(an.getName()));
			}
			device.setId(generateXmiId(an.getName()));
			device.setName(an.getName());
			device.setBlockId(generateId(an.getName()));
			device.setSubSystemId(generateId(an.getName()));
		}
		String filePath = project.getFolderPath() + "actors.xmi";
		inputData("actors", actors);
		generateCodeFile(filePath, TEMPLATE_NAME);
		logger.info(filePath);
		return FileUtil.getRootPath() + filePath;
	}
	
	private String generateXmiId(String data){
		String prefix = "GUID+";
		int length = 32;
		char c = '-';
		int firstIndex = 8;
		int secondIndex = 13;
		int thirdIndex = 18;
		int fourthIndex = 23;
		
		MD5 md5 = new MD5();
		String uri = md5.getMD5ofStr(data + System.currentTimeMillis());
		StringBuilder hash = new StringBuilder(uri.substring(0, length).toLowerCase());
		hash.insert(firstIndex, c).insert(secondIndex, c).insert(thirdIndex, c).insert(fourthIndex, c);
		hash.insert(0, prefix);
		return hash.toString();
	}
	
	private String generateId(String data){
		String prefix = "__";
		int length = 21;
		MD5 md5 = new MD5();
		String uri = md5.getMD5ofStr(data + System.currentTimeMillis());
		StringBuilder hash = new StringBuilder(prefix).append(uri.substring(0, length));
		logger.info(hash.toString());
		return hash.toString();
	}

}
